package com.demo.schedule.medicine;

import cn.hutool.core.date.DateUtil;
import com.demo.entity.Medicine;
import com.demo.entity.MessageRule;
import com.demo.entity.Patient;
import com.demo.entity.VtePreventiveDoctorAdvice;
import com.demo.enums.MessageRemindEnum;
import com.demo.enums.MessageRuleLoopWarningEnum;
import com.demo.enums.MessageSourceEnum;
import com.demo.mapper.MedicineMapper;
import com.demo.mapper.MessageRuleMapper;
import com.demo.mapper.PatientMapper;
import com.demo.service.IMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class MedicineRemindThread extends Thread {

    private MedicineMapper medicineMapper;
    private MessageRuleMapper messageRuleMapper;
    private PatientMapper patientMapper;
    private IMessageService messageService;
    private VtePreventiveDoctorAdvice vtePreventiveDoctorAdvice;//提醒指定的医嘱

    private Medicine medicine;
    private MessageRule messageRule;

    public MedicineRemindThread(Medicine medicine, MessageRule messageRule, VtePreventiveDoctorAdvice vtePreventiveDoctorAdvice, ApplicationContext applicationContext) {
        this.setName(String.format("药物:%s;规则:%s", medicine.getMedicineName(), messageRule.getMessageRuleId()));
        this.medicine = medicine;
        this.messageRule = messageRule;
        this.vtePreventiveDoctorAdvice = vtePreventiveDoctorAdvice;
        this.medicineMapper = applicationContext.getBean(MedicineMapper.class);
        this.messageRuleMapper = applicationContext.getBean(MessageRuleMapper.class);
        this.patientMapper = applicationContext.getBean(PatientMapper.class);
        this.messageService = applicationContext.getBean(IMessageService.class);
    }

    @Override
    public void run() {
        log.info("药物提醒 {}线程正在执行.....", this.getName());
        try {
            if (!check()) {
                return;
            }
            Date sendDate = new Date();

            Date createdTime = vtePreventiveDoctorAdvice.getCreatedTime();
            Date nowDate = new Date();
            long betweenDay = DateUtil.betweenDay(createdTime, nowDate, true);
            Date todaySignDate = DateUtil.offsetDay(createdTime, Integer.parseInt(String.valueOf(betweenDay)));//将开药日期偏移到今天,用于换算提醒时间
            if (todaySignDate.getTime() < nowDate.getTime()) {
                sendDate = todaySignDate;
            }

            Patient patient = patientMapper.getDetailsById(vtePreventiveDoctorAdvice.getPatientId());
            Map<String, Object> messageContent = new HashMap<>();
            messageContent.put("message_text", messageRule.getMessageContent());
            messageContent.put("bed_id", patient.getBedId());
            messageContent.put("bed_name", patient.getBedName());
            messageContent.put("patient_name", patient.getPatientName());
            messageContent.put("dept_name", patient.getDeptName());
            messageContent.put("dept_sn", patient.getDeptSn());
            messageService.sendMessageNotification(MessageRemindEnum.YI_ZHU_REMIND, patient, MessageSourceEnum.HIS_PUSH, messageContent, 0, sendDate, vtePreventiveDoctorAdvice.getDoctorAdviceId());

            if (Objects.equals(messageRule.getIsLoopWarning().intValue(), MessageRuleLoopWarningEnum.YES.getValue())) {
                // 将下一次提醒添加到线程池
                Thread.sleep(2 * 60 * 1000);//睡眠 2 分钟
                MedicineRemindSchedule.addMedicineRemindTask(medicine, messageRule, vtePreventiveDoctorAdvice);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Thread-Exception error: {}", e);
        }
    }

    /**
     * 发送消息提醒前置检查
     * @return
     */
    public boolean check() {
        messageRule = messageRuleMapper.queryByIdEffectiveAndInLoop(messageRule.getMessageRuleId());
        if (messageRule == null) {
            log.info("规则已经删除");
            return false;
        }
        medicine = medicineMapper.queryByIdInEffective(medicine.getMedicineId());
        if (medicine == null) {
            log.info("药品不存在或删除");
            return false;
        }
        return true;
    }
}
